home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / TUTOROOT.PAK / STEP12DV.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  10KB  |  429 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1994 by Borland International
  3. //   Tutorial application -- step12dv.cpp
  4. //----------------------------------------------------------------------------
  5. #include <owl/pch.h>
  6. #include <owl/dc.h>
  7. #include <owl/inputdia.h>
  8. #include <owl/chooseco.h>
  9. #include <owl/gdiobjec.h>
  10. #include <owl/docmanag.h>
  11. #include <owl/filedoc.h>
  12. #include <classlib/arrays.h>
  13. #include "step12dv.rc"
  14.  
  15. typedef TArray<TPoint> TPoints;
  16. typedef TArrayIterator<TPoint> TPointsIterator;
  17.  
  18. class TLine : public TPoints {
  19.   public:
  20.     // Constructor to allow construction from a color and a pen size.
  21.     // Also serves as default constructor.
  22.     TLine(const TColor& color = TColor(0), int penSize = 1) :
  23.       TPoints(10, 0, 10), PenSize(penSize), Color(color) {}
  24.  
  25.     // Functions to modify and query pen attributes.
  26.     int QueryPenSize() const
  27.     {
  28.       return PenSize;
  29.     }
  30.     const TColor& QueryColor() const
  31.     {
  32.       return Color;
  33.     }
  34.     void SetPen(const TColor& newColor, int penSize = 0);
  35.     void SetPen(int penSize);
  36.  
  37.     // TLine draws itself.  Returns true if everything went OK.
  38.     virtual bool Draw(TDC&) const;
  39.  
  40.     // The == operator must be defined for the container class, even if unused
  41.     bool operator ==(const TLine& other) const
  42.     {
  43.       return &other == this;
  44.     }
  45.  
  46.     friend ostream& operator <<(ostream& os, const TLine& line);
  47.     friend istream& operator >>(istream& is, TLine& line);
  48.  
  49.   protected:
  50.     int PenSize;
  51.     TColor Color;
  52. };
  53.  
  54. typedef TArray<TLine> TLines;
  55. typedef TArrayIterator<TLine> TLinesIterator;
  56.  
  57. class _USERCLASS TDrawDocument : public TFileDocument {
  58.   public:
  59.     TDrawDocument(TDocument* parent = 0) : TFileDocument(parent), Lines(0) {}
  60.    ~TDrawDocument()
  61.     {
  62.       delete Lines;
  63.     }
  64.  
  65.     // implement virtual methods of TDocument
  66.     bool   Open(int mode, const char far* path=0);
  67.     bool   Close();
  68.     bool   IsOpen()
  69.     {
  70.       return Lines != 0;
  71.     }
  72.     bool   Commit(bool force = false);
  73.     bool   Revert(bool clear = false);
  74.  
  75.     // data access functions
  76.     const TLine* GetLine(unsigned int index);
  77.     int    AddLine(TLine& line);
  78.  
  79.   protected:
  80.     TLines* Lines;
  81. };
  82.  
  83. class _USERCLASS TDrawView : public TWindowView {
  84.   public:
  85.     TDrawView(TDrawDocument& doc, TWindow* parent = 0);
  86.    ~TDrawView()
  87.     {
  88.       delete DragDC;
  89.       delete Line;
  90.     }
  91.     static const char far* StaticName()
  92.     {
  93.       return "Draw View";
  94.     }
  95.  
  96.   protected:
  97.     TDrawDocument* DrawDoc;  // same as Doc member, but cast to derived class
  98.     TDC* DragDC;
  99.     TPen*  Pen;
  100.     TLine* Line; // To hold a single line sent or received from document
  101.     void GetPenSize(); // GetPenSize always calls Line->SetPen().
  102.  
  103.     // Message response functions
  104.     void EvLButtonDown(uint, TPoint&);
  105.     void EvRButtonDown(uint, TPoint&);
  106.     void EvMouseMove(uint, TPoint&);
  107.     void EvLButtonUp(uint, TPoint&);
  108.     void Paint(TDC&, bool, TRect&);
  109.     void CmPenSize();
  110.     void CmPenColor();
  111.  
  112.     // Document notifications
  113.     bool VnCommit(bool force);
  114.     bool VnRevert(bool clear);
  115.  
  116.   DECLARE_RESPONSE_TABLE(TDrawView);
  117. };
  118.  
  119. DEFINE_DOC_TEMPLATE_CLASS(TDrawDocument, TDrawView,   DrawTemplate);
  120. DrawTemplate drawTpl("Point Files (*.PTS)","*.pts",0,"PTS",dtAutoDelete|dtUpdateDir);
  121.  
  122. void
  123. TLine::SetPen(int penSize)
  124. {
  125.   if (penSize < 1)
  126.     PenSize = 1;
  127.   else
  128.     PenSize = penSize;
  129. }
  130.  
  131. void
  132. TLine::SetPen(const TColor& newColor, int penSize)
  133. {
  134.   // If penSize isn't the default (0), set PenSize to the new size.
  135.   if (penSize)
  136.     PenSize = penSize;
  137.  
  138.   Color = newColor;
  139. }
  140.  
  141. bool
  142. TLine::Draw(TDC& dc) const
  143. {
  144.   // Set pen for the dc to the values for this line
  145.   TPen pen(Color, PenSize);
  146.   dc.SelectObject(pen);
  147.  
  148.   // Iterates through the points in the line i.
  149.   TPointsIterator j(*this);
  150.   bool first = true;
  151.  
  152.   while (j) {
  153.     TPoint p = j++;
  154.  
  155.     if (!first)
  156.       dc.LineTo(p);
  157.     else {
  158.       dc.MoveTo(p);
  159.       first = false;
  160.     }
  161.   }
  162.   dc.RestorePen();
  163.   return true;
  164. }
  165.  
  166. ostream&
  167. operator <<(ostream& os, const TLine& line)
  168. {
  169.   // Write the number of points in the line
  170.   os << line.GetItemsInContainer();
  171.  
  172.   // Get and write pen attributes.
  173.   os << ' ' << line.Color << ' ' << line.PenSize;
  174.  
  175.   // Get an iterator for the array of points
  176.   TPointsIterator j(line);
  177.  
  178.   // While the iterator is valid (i.e. we haven't run out of points)
  179.   while(j)
  180.     // Write the point from the iterator and increment the array.
  181.     os << j++;
  182.   os << '\n';
  183.  
  184.   // return the stream object
  185.   return os;
  186. }
  187.  
  188. istream&
  189. operator >>(istream& is, TLine& line)
  190. {
  191.   unsigned numPoints;
  192.   is >> numPoints;
  193.  
  194.   COLORREF color;
  195.   int penSize;
  196.   is >> color >> penSize;
  197.   line.SetPen(TColor(color), penSize);
  198.  
  199.   while (numPoints--) {
  200.     TPoint point;
  201.     is >> point;
  202.     line.Add(point);
  203.   }
  204.  
  205.   // return the stream object
  206.   return is;
  207. }
  208.  
  209. bool
  210. TDrawDocument::Commit(bool force)
  211. {
  212.   if (!IsDirty() && !force)
  213.     return true;
  214.  
  215.   TOutStream* os = OutStream(ofWrite);
  216.   if (!os)
  217.     return false;
  218.  
  219.   // Write the number of lines in the figure
  220.   *os << Lines->GetItemsInContainer();
  221.  
  222.   // Append a description using a resource string
  223.   *os << ' ' << string(*GetDocManager().GetApplication(),IDS_FILEINFO) << '\n';
  224.  
  225.   // Get an iterator for the array of lines
  226.   TLinesIterator i(*Lines);
  227.  
  228.   // While the iterator is valid (i.e. we haven't run out of lines)
  229.   while (i) {
  230.     // Copy the current line from the iterator and increment the array.
  231.     *os << i++;
  232.   }
  233.   delete os;
  234.  
  235.   SetDirty(false);
  236.   return true;
  237. }
  238.  
  239. bool
  240. TDrawDocument::Revert(bool clear)
  241. {
  242.   if (!TFileDocument::Revert(clear))
  243.     return false;
  244.   if (!clear)
  245.     Open(0);
  246.   return true;
  247. }
  248.  
  249. bool
  250. TDrawDocument::Open(int /*mode*/, const char far* path)
  251. {
  252.   Lines = new TLines(5, 0, 5);
  253.   if (path)
  254.     SetDocPath(path);
  255.   if (GetDocPath()) {
  256.     TInStream* is = InStream(ofRead);
  257.     if (!is)
  258.       return false;
  259.  
  260.     unsigned numLines;
  261.     char fileinfo[100];
  262.     *is >> numLines;
  263.     is->getline(fileinfo, sizeof(fileinfo));
  264.     while (numLines--) {
  265.       TLine line;
  266.       *is >> line;
  267.       Lines->Add(line);
  268.     }
  269.     delete is;
  270.   }
  271.   SetDirty(false);
  272.   return true;
  273. }
  274.  
  275. bool
  276. TDrawDocument::Close()
  277. {
  278.   delete Lines;
  279.   Lines = 0;
  280.   return true;
  281. }
  282.  
  283. const TLine*
  284. TDrawDocument::GetLine(unsigned int index)
  285. {
  286.   if (!IsOpen() && !Open(ofRead | ofWrite))
  287.     return 0;
  288.   return index < Lines->GetItemsInContainer() ? &(*Lines)[index] : 0;
  289. }
  290.  
  291. int
  292. TDrawDocument::AddLine(TLine& line)
  293. {
  294.   int index = Lines->GetItemsInContainer();
  295.   Lines->Add(line);
  296.   SetDirty(true);
  297.   return index;
  298. }
  299.  
  300. DEFINE_RESPONSE_TABLE1(TDrawView, TWindowView)
  301.   EV_WM_LBUTTONDOWN,
  302.   EV_WM_RBUTTONDOWN,
  303.   EV_WM_MOUSEMOVE,
  304.   EV_WM_LBUTTONUP,
  305.   EV_COMMAND(CM_PENSIZE, CmPenSize),
  306.   EV_COMMAND(CM_PENCOLOR, CmPenColor),
  307.   EV_VN_COMMIT,
  308.   EV_VN_REVERT,
  309. END_RESPONSE_TABLE;
  310.  
  311. TDrawView::TDrawView(TDrawDocument& doc,TWindow* parent) :
  312.   TWindowView(doc, parent), DrawDoc(&doc)
  313. {
  314.   DragDC  = 0;
  315.   Line    = new TLine(TColor::Black, 1);
  316.   SetViewMenu(new TMenuDescr(IDM_DRAWVIEW,0,1,0,0,0,0));
  317. }
  318.  
  319. void
  320. TDrawView::EvLButtonDown(uint, TPoint& point)
  321. {
  322.   if (!DragDC) {
  323.     SetCapture();
  324.     DragDC = new TClientDC(*this);
  325.     Pen = new TPen(Line->QueryColor(), Line->QueryPenSize());
  326.     DragDC->SelectObject(*Pen);
  327.     DragDC->MoveTo(point);
  328.     Line->Add(point);
  329.   }
  330. }
  331.  
  332. void
  333. TDrawView::EvRButtonDown(uint, TPoint&)
  334. {
  335.   GetPenSize();
  336. }
  337.  
  338. void
  339. TDrawView::EvMouseMove(uint, TPoint& point)
  340. {
  341.   if (DragDC) {
  342.     DragDC->LineTo(point);
  343.     Line->Add(point);
  344.   }
  345. }
  346.  
  347. void
  348. TDrawView::EvLButtonUp(uint, TPoint&)
  349. {
  350.   if (DragDC) {
  351.     ReleaseCapture();
  352.     if (Line->GetItemsInContainer() > 1)
  353.       DrawDoc->AddLine(*Line);
  354.     Line->Flush();
  355.     delete DragDC;
  356.     delete Pen;
  357.     DragDC = 0;
  358.   }
  359. }
  360.  
  361. void
  362. TDrawView::CmPenSize()
  363. {
  364.   GetPenSize();
  365. }
  366.  
  367. void
  368. TDrawView::CmPenColor()
  369. {
  370.   TChooseColorDialog::TData colors;
  371.   static TColor custColors[16] =
  372.   {
  373.     0x010101L, 0x101010L, 0x202020L, 0x303030L,
  374.     0x404040L, 0x505050L, 0x606060L, 0x707070L,
  375.     0x808080L, 0x909090L, 0xA0A0A0L, 0xB0B0B0L,
  376.     0xC0C0C0L, 0xD0D0D0L, 0xE0E0E0L, 0xF0F0F0L
  377.   };
  378.  
  379.   colors.Flags = CC_RGBINIT;
  380.   colors.Color = TColor(Line->QueryColor());
  381.   colors.CustColors = custColors;
  382.   if (TChooseColorDialog(this, colors).Execute() == IDOK)
  383.     Line->SetPen(colors.Color);
  384. }
  385.  
  386. void
  387. TDrawView::GetPenSize()
  388. {
  389.   char inputText[6];
  390.   int penSize = Line->QueryPenSize();
  391.  
  392.   wsprintf(inputText, "%d", penSize);
  393.   if (TInputDialog(this, "Line Thickness",
  394.                         "Input a new thickness:",
  395.                         inputText,
  396.                         sizeof(inputText),::Module).Execute() == IDOK) {
  397.     penSize = atoi(inputText);
  398.  
  399.     if (penSize < 1)
  400.       penSize = 1;
  401.   }
  402.   Line->SetPen(penSize);
  403. }
  404.  
  405. void
  406. TDrawView::Paint(TDC& dc, bool, TRect&)
  407. {
  408.   // Iterates through the array of line objects.
  409.   int i = 0;
  410.   const TLine* line;
  411.   while ((line = DrawDoc->GetLine(i++)) != 0)
  412.     line->Draw(dc);
  413. }
  414.  
  415. bool
  416. TDrawView::VnCommit(bool /*force*/)
  417. {
  418.   // nothing to do here, no data held in view
  419.   return true;
  420. }
  421.  
  422. bool
  423. TDrawView::VnRevert(bool /*clear*/)
  424. {
  425.   Invalidate();  // force full repaint
  426.   return true;
  427. }
  428.  
  429.